import math
from texttable import Texttable
import importlib
import sys


class ItemBasedCF:
    def __init__(self, train_file):
        self.train_file = train_file
        self.readData()

    """
    读取数据，处理成字典格式
    生成用户数据集： 用户，  兴趣程度， 物品
    {用户i： {物品1：兴趣程度, 物品2：兴趣程度， 物品3：兴趣程度}}
    """

    def readData(self):
        self.train = dict()
        # print('train_file:', self.train_file)
        for line in self.train_file:
            # print('type(line):', type(line))
            user, score, item = line.strip().split(",")
            self.train.setdefault(user, {})
            self.train[user][item] = int(float(score))

    """
        N: {物品1： 2，  物品2：  5，  物品3： 1}
        C: {
            物品1 ： {物品2： 2，  物品3： 1}，  
            物品2 ： {物品1： 2，  物品3： 2，  物品4： 1}
            }
        """

    def ItemSimilarity(self):
        N = dict()  # 物品被多少个不同用户购买
        C = dict()  # 物品和物品的共现矩阵
        for user, items in self.train.items():
            # print('user:', user)
            # print('item:', items)
            for ikey in items.keys():  # ikey: {'a': 1, 'b': 1, 'd': 1}
                # print('ikey:', ikey)
                N.setdefault(ikey, 0)
                N[ikey] += 1

                C.setdefault(ikey, {})
                for jkey in items.keys():  # 物品和物品的共现矩阵 jkey: {'a': 1, 'b': 1, 'd': 1}
                    if ikey == jkey:
                        continue
                    # print('jkey:', jkey)
                    C[ikey].setdefault(jkey, 0)
                    # C[ikey][jkey] += 1
                    C[ikey][jkey] += 1 / math.log(1 + len(items) * 1.0)  # 用用户活跃度来修正相似度，len(items)来衡量用户活跃度

        # print('N:', N)
        # print('C:', C)

        # 根据N，C计算物品之间的相似度
        # 根据C得到物品和物品共现的次数，根据N得到物品分别出现的次数
        self.W = dict()
        self.W_max = dict()  # 记录每一列的最大值
        for ikey, relateij in C.items():
            # print('ikey:', ikey)
            # print('relateij:', relateij)
            self.W.setdefault(ikey, {})
            for jkey, Wij in relateij.items():
                self.W_max.setdefault(jkey, 0.0)  # 初始化当列最大值为0
                self.W[ikey][jkey] = Wij / (math.sqrt(N[ikey] * N[jkey]))  # 计算相似度
                if self.W[ikey][jkey] > self.W_max[jkey]:
                    self.W_max[jkey] = self.W[ikey][jkey]  # 更新列中最大值
                    # print('jkey:', jkey, 'self.W_max:', self.W_max[jkey])

        # 归一化处理, Wij / Wij_max
        for ikey, relateij in C.items():
            for jkey, Wij in relateij.items():
                self.W[ikey][jkey] = self.W[ikey][jkey] / self.W_max[jkey]


                for k, v in self.W.items():
                 print(k + ':' + str(v))